package com.lihaozhe.orderservice.service;

import com.lihaozhe.productservice.dto.ProductDTO;
import com.lihaozhe.userservice.dto.UserDTO;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 服务发现工具类
 * 演示如何通过Eureka发现和调用其他服务
 *
 * @author 李昊哲
 * @version 1.0.0
 */
@Service
public class ServiceDiscoveryService {
  private final RestClient restClient;
  private final DiscoveryClient discoveryClient;

  /**
   * 构造函数，注入依赖
   */
  public ServiceDiscoveryService(RestClient restClient, DiscoveryClient discoveryClient) {
    this.restClient = restClient;
    this.discoveryClient = discoveryClient;
  }

  /**
   * 获取所有注册的服务名称
   */
  public List<String> getServices() {
    return this.discoveryClient.getServices();
  }

  /**
   * 根据服务名称获取服务实例
   */
  public List<ServiceInstance> getServiceInstances(String serviceName) {
    return discoveryClient.getInstances(serviceName);
  }

  /**
   * 获取用户服务的基础URL
   * 从Eureka获取用户服务的地址
   */
  public String getUserServiceUrl() {
    List<ServiceInstance> instances = getServiceInstances("user-service");
    if (instances.isEmpty()) {
      throw new RuntimeException("用户服务未找到");
    }
    // 获取第一个可用的实例（实际生产环境应该实现负载均衡）
    ServiceInstance instance = instances.getFirst();
    return instance.getUri().toString();
  }

  /**
   * 获取商品服务的基础URL
   */
  public String getProductServiceUrl() {
    List<ServiceInstance> instances = getServiceInstances("product-service");
    if (instances.isEmpty()) {
      throw new RuntimeException("商品服务未找到");
    }
    ServiceInstance instance = instances.get(ThreadLocalRandom.current().nextInt(instances.size()));
    return instance.getUri().toString();
  }

  /**
   * 通过服务发现调用用户服务获取用户信息
   */
  public UserDTO getUserById(Long userId) {
    String userServiceUrl = getUserServiceUrl();
    String url = userServiceUrl + "/api/users/" + userId;

    try {
      return restClient.get()
          .uri(url)
          .retrieve()
          .body(UserDTO.class);
    } catch (Exception e) {
      throw new RuntimeException("调用用户服务失败: " + e.getMessage());
    }
  }

  /**
   * 通过服务发现调用商品服务获取商品信息
   */
  public ProductDTO getProductById(Long productId) {
    String productServiceUrl = getProductServiceUrl();
    String url = productServiceUrl + "/api/products/" + productId;
    IO.println("获取商品信息-商品服务：URL: " + url);
    try {
      return restClient.get()
          .uri(url)
          .retrieve()
          .body(ProductDTO.class);
    } catch (Exception e) {
      throw new RuntimeException("调用商品服务失败: " + e.getMessage());
    }
  }

  /**
   * 通过服务发现调用商品服务更新库存
   */
  public boolean updateProductStock(Long productId, Integer quantity) {
    String productServiceUrl = getProductServiceUrl();
    String url = productServiceUrl + "/api/products/" + productId + "/stock";
    IO.println("更新库存-商品服务：URL: " + url);

    try {
      String requestBody = String.format("{\"quantity\": %d}", quantity);

      String response = restClient.put()
          .uri(url)
          .header("Content-Type", "application/json")
          .body(requestBody)
          .retrieve()
          .body(String.class);

      return response != null && response.contains("success");
    } catch (Exception e) {
      throw new RuntimeException("更新商品库存失败: " + e.getMessage());
    }
  }
}
